<template>
  <div class="containers" ref="content" style="border: 1px solid mediumpurple">
    <el-row>
      <el-col :span="20" style="height: calc(100vh - 150px);">
        <div class="canvas" ref="canvas">
          <el-button-group style="position: absolute; left: 1.25rem; bottom: 0rem; z-index: 999">
            <el-button @click="deployDiagram" type="primary" size="mini"> 部署</el-button>
            <el-button @click="showImprotDialog=true" type="primary" size="mini">导入</el-button>
            <router-link :to="{name:'ProcessList'}"><el-button @click="showImprotDialog=true" type="primary" size="mini">已部署列表</el-button></router-link>
          </el-button-group>
        </div>

      </el-col>
      <el-col :span="4" style="height: calc(100vh - 122px);">
        <div ref="panel" id="js-properties-panel" class="panel"></div>
      </el-col>
    </el-row>
    <el-dialog title="导入图表" :visible.sync="showImprotDialog">
      <el-form size="small" v-model="DiagramForm">
        <el-form-item label="粘贴xml代码">
          <el-input v-model="DiagramForm.xml" type="textarea" rows="15"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showImprotDialog = false">取 消</el-button>
        <el-button type="primary" @click="improtDiagram">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import BpmnModeler from "bpmn-js/lib/Modeler";
import propertiesPanelModule from "bpmn-js-properties-panel";
import propertiesProviderModule from "bpmn-js-properties-panel-activiti/lib/provider/activiti";
import activitiModdleDescriptor from "@/assets/activiti.json";
import translations from "@/assets/translations.js";
import customTranslate from "@/assets/customTranslate";
import "bpmn-js/dist/assets/diagram-js.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
import "bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css";

export default {
  name: "BPMN",
  data() {
    return {
      bpmnModeler: null,
      container: null,
      canvas: null,
      initialDiagram: `<?xml version="1.0" encoding="UTF-8"?>
						<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="bpmn-js (https://demo.bpmn.io)" exporterVersion="5.1.2">
						<process id="Process_1" isExecutable="true">
						    <startEvent id="StartEvent_1y45yut" name="开始">
						    <outgoing>SequenceFlow_0h21x7r</outgoing>
						    </startEvent>
						    <task id="Task_1hcentk">
						    <incoming>SequenceFlow_0h21x7r</incoming>
						    </task>
						    <sequenceFlow id="SequenceFlow_0h21x7r" sourceRef="StartEvent_1y45yut" targetRef="Task_1hcentk" />
						</process>
						<bpmndi:BPMNDiagram id="BpmnDiagram_1">
						    <bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="Process_1">
						    <bpmndi:BPMNShape id="StartEvent_1y45yut_di" bpmnElement="StartEvent_1y45yut">
						        <omgdc:Bounds x="152" y="102" width="36" height="36" />
						        <bpmndi:BPMNLabel>
						        <omgdc:Bounds x="160" y="145" width="22" height="14" />
						        </bpmndi:BPMNLabel>
						    </bpmndi:BPMNShape>
						    <bpmndi:BPMNShape id="Task_1hcentk_di" bpmnElement="Task_1hcentk">
						        <omgdc:Bounds x="240" y="80" width="100" height="80" />
						    </bpmndi:BPMNShape>
						    <bpmndi:BPMNEdge id="SequenceFlow_0h21x7r_di" bpmnElement="SequenceFlow_0h21x7r">
						        <omgdi:waypoint x="188" y="120" />
						        <omgdi:waypoint x="240" y="120" />
						    </bpmndi:BPMNEdge>
						    </bpmndi:BPMNPlane>
						</bpmndi:BPMNDiagram>
						</definitions>`,
      showImprotDialog: false,
      DiagramForm: {
        xml: ''
      }
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      // 获取到属性ref为"content"的dom节点
      this.container = this.$refs.content;
      // 获取到属性ref为"canvas"的dom节点
      const canvas = this.$refs.canvas;
      var customTranslateModule = {
        translate: ["value", customTranslate],
      };
      // 建模
      this.bpmnModeler = new BpmnModeler({
        container: canvas,
        // 使用快捷键
        keyboard: {
          bindTo: window,
        },
        //添加控制板
        propertiesPanel: {
          parent: "#js-properties-panel",
        },
        additionalModules: [
          propertiesPanelModule,
          propertiesProviderModule,
          customTranslateModule,
        ],
        moddleExtensions: {
          activiti: activitiModdleDescriptor,
        },
      });
      console.log(this.bpmnModeler);
      this.createNewDiagram();
    },

    // 使用导入 xml 的方式创建流程图
    createNewDiagram() {
      if (this.bpmnModeler) {
        this.bpmnModeler.importXML(this.initialDiagram).then((result) => {
          const { warnings } = result;
          if (warnings) {
            console.warn('Warnings during import:', warnings);
          }
          console.log("Diagram successfully imported.");
        }).catch((error) => {
          console.error('Failed to import diagram', error);
        });
      } else {
        console.error("bpmnModeler is not initialized.");
      }
    },
    customTranslate(template, replacements) {
      replacements = replacements || {};

      // Translate
      template = translations[template] || template;

      // Replace
      return template.replace(/{([^}]+)}/g, function (_, key) {
        return replacements[key] || '{' + key + '}';
      });
    },
    deployDiagram() {
      this.bpmnModeler.saveXML({format: true}, (err, xml) => {
        if (err) {
          console.log("保存失败", err)
          return
        }
        console.log(xml)
        this.$http.post("/process/uploadXML", xml, {
          headers: {
            "Content-Type": "application/xml"
          }
        }).then((response) => {
          if (response.data.code == 1) {
            alert("在线部署流程成功")
          } else {
            alert("部署失败")
          }
        })
      })
    },
    importXMLPromise(xml) {
      return new Promise((resolve, reject) => {
        this.bpmnModeler.importXML(xml, (err, warnings) => {
          if (err) {
            reject(err);
          } else {
            resolve(warnings);
          }
        });
      });
    },
    improtDiagram() {
      if (this.DiagramForm.xml) {
        this.importXMLPromise(this.DiagramForm.xml).then(() => {
          this.showImprotDialog = false
          this.$message.success("流程导入成功")
          this.bpmnModeler.get('canvas').zoom('fit-viewport');
        })
        .catch((error) => {
          console.error('导入流程失败', error);
          this.$message.error('导入失败，请检查XML格式');
        });
      }
      else {
        this.$message.warning('请粘贴XML代码');
      }
    }
  },

}
</script>


<style scoped>
.containers {
  /* 使用网格作为背景 */
  background: white;
  overflow: no-display;
  box-sizing: border-box;
  background-image: linear-gradient(
      90deg,
      rgba(220, 220, 220, 0.5) 6%,
      transparent 0
  ),
  linear-gradient(rgba(192, 192, 192, 0.5) 6%, transparent 0);
  background-size: 12px 12px;
  width: 100%;
  height: calc(100vh - 120px);
  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
  font-size: 0.75rem;
  font-weight: lighter;
}

.canvas {
  width: 100%;
  height: 100%;
  position: relative;
}

.panel {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
}
</style>
